/**
* AutoSWF - Cody Cushing. March 26, 2009
* Copyright (c) 2009 Cody Cushing
* No use restrictions. Maintain this notice in all versions. 
**/

package com.autoswf.automator
{
	import com.autoswf.core.MockLink;
	import com.autoswf.core.Transport;
	
	import flash.events.Event;
	import flash.utils.setTimeout;
	
	import flexunit.framework.TestCase;

	public class AutomationObserverTest extends TestCase
	{
		private var descriptor1:XML = <node delay="2" className="flash.events::Event" type="change" path="link"/>;
		private var descriptor2:XML = <node delay="2" className="flash.events::MouseEvent" type="click" path="link"/>;
		private var changeEventDescriptor:XML = <node delay="0" className="flash.events::Event" type="change" path="change"/>;
		
		private var automationObserver:AutomationObserver;
		private var mockClient:MockAutomationClient;
		
		public function AutomationObserverTest(methodName:String=null)
		{
			super(methodName);
		}
		
		override public function setUp():void
		{
			mockClient = new MockAutomationClient();
			automationObserver = new AutomationObserver("AutomationObserver");
		} 
		
		/**
		 * Test adding subscribers to automation observer. Supports multiple clients for logging consoles, etc. 
		 */		
		public function testAddSubscriber():void
		{
			var mockClient2:MockAutomationClient2 = new MockAutomationClient2();
			
			automationObserver.addSubscriber(mockClient);
			automationObserver.addSubscriber(mockClient2);
			assertTrue("failed to indicate client", automationObserver.hasSubscriber(mockClient));
			
			automationObserver.removeSubscriber(mockClient);
			assertFalse("indicated client after removal", automationObserver.hasSubscriber(mockClient));
			assertTrue("failed to indicate client", automationObserver.hasSubscriber(mockClient2));
		}
		
		/**
		 * Test observer serializes events to into descriptor format and passes descriptors to clients. 
		 */		
		public function testSerialize():void
		{
			automationObserver.addSubscriber(mockClient);
			automationObserver.sendUp(new Transport(new Event(Event.CHANGE)));
			mockClient.descriptor.@delay = 0; // cannot control machine delay, overwrite.
			assertEquals("failed to deserialize event", changeEventDescriptor.toXMLString(), mockClient.descriptor.toXMLString());
		}
		
		/**
		 * Tests observer deserializes a descriptor into a transport message and passes it down the tree. 
		 */		
		public function testRemoteLoad():void
		{
			var mockLink:MockLink = new MockLink("link");
			automationObserver.addChildLink(mockLink);
			automationObserver.addSubscriber(mockClient);
			
			mockClient.executeRemoteLoadCommand(descriptor1.toXMLString());
			assertEquals("failed to automate event", "change", mockLink.sendDownResult);
			
			mockClient.executeRemoteLoadCommand(descriptor2.toXMLString());
			assertEquals("failed to automate mouse event", "click", mockLink.sendDownResult);
		}
		
		/**
		 * Tests that proper delay intervals are added to descriptors when they are created. 
		 */		
		public function testDelayStamping():void
		{
			automationObserver.addSubscriber(mockClient);

			setTimeout(function():void
			{
				automationObserver.sendUp(new Transport(new Event(Event.CHANGE)));
				assertTrue("did not add timestamp to descriptor", int(mockClient.descriptor.@delay) > 3);
			}, 20);
		}
		
	}
}